package object

import (
	"lark/src/ast"
	"path/filepath"
)

// 符号表

// Symbol 表示一个符号
type Symbol struct {
	Module     string // 模块名
	Name       string
	Value      Object // 可以是AST节点或计算后的值
	Type       string
	Node       ast.Node // 原始AST节点
	IsComputed bool     // 是否参与计算（关键标记）
	Exported   bool     // 是否导出(公共或私有)如函数、变量等
}

type Environment struct {
	name   string
	store  map[string]Symbol //map
	parent *Environment      //父作用域, 指向外层环境的指针，实现作用域链
}

func NewEnvironment() *Environment {
	// 初始化符号表
	s := make(map[string]Symbol)
	return &Environment{name: "main", store: s, parent: nil}
}
func (e *Environment) Get(name string) (Symbol, bool) {
	obj, ok := e.store[name]
	if !ok && e.parent != nil {
		obj, ok = e.parent.Get(name)
	}
	return obj, ok
}

func (e *Environment) Set(name string, val Symbol) Symbol {
	//获取路径最后的名称
	lastName := filepath.Base(e.name)
	val.Module = lastName
	e.store[name] = val
	return val
}

// 创建嵌套环境，保留对外层环境的引用
func NewEnclosedEnvironment(parent *Environment, name string) *Environment {
	env := NewEnvironment()
	env.name = name
	env.parent = parent
	return env
}
